package gvjclient.ui;
/*
Copyright 2010 Arpit Sud
This file is part of gv-jclient. (http://code.google.com/p/gv-jclient/)
gv-jclient is an Unofficial Java client for Google Voice.

gv-jclient is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

gv-jclient is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with gv-jclient.  If not, see <http://www.gnu.org/licenses/>.
*/

import gvjclient.GVJclient;
import gvjclient.actions.CallAction;
import gvjclient.actions.LoginAction;
import gvjclient.actions.SendSMSAction;
import gvjclient.types.Account;
import gvjclient.types.Contact;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Scanner;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JPopupMenu.Separator;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import com.techventus.server.voice.datatypes.Phone;


public class GVJclientUI extends JFrame {

	public static GVJclientUI INSTANCE = new GVJclientUI();
	private MainPanel mainPanel;
	private AccountsTree accountsTree;
	private RightPanel rightPanel;
	private MainToolbar mainToolbar;
	private GVJclient[] gvjclients;
	private String profileName = "Default-Profile";
	private DefaultMutableTreeNode top;
	
	public static void main(String[] args) {
		 try {
		        UIManager.setLookAndFeel(
		            UIManager.getSystemLookAndFeelClassName());
		    } 
		    catch (UnsupportedLookAndFeelException e) {
		       // handle exception
		    }
		    catch (ClassNotFoundException e) {
		       // handle exception
		    }
		    catch (InstantiationException e) {
		       // handle exception
		    }
		    catch (IllegalAccessException e) {
		       // handle exception
		    }
	        UIManager.put("swing.boldMetal", Boolean.FALSE);


		GVJclientUI app = GVJclientUI.get_instance();
		app.init();
		app.initTray();
		app.setVisible(true);
		app.loginAll();

	}
	
	public static GVJclientUI get_instance() {
		return INSTANCE;
	}
	
	public GVJclient[] getClients()
	{
		return this.gvjclients;
	}
	
	public GVJclient[] getLoggedInClients()
	{
		int i;
		ArrayList<GVJclient> arrayList = new ArrayList<GVJclient>();
		for(i=0;i<this.gvjclients.length;i++)
		{
			if(gvjclients[i].isLoggedIn())
				arrayList.add(gvjclients[i]);
		}
		return (GVJclient[])arrayList.toArray(new GVJclient[arrayList.size()]);
	}
	
	private GVJclientUI() throws HeadlessException {
		super("GV-Java Client");
	}
	
	private void initTray()
	{
	     if (SystemTray.isSupported())
	     {
	    	 PopupMenu popup = new PopupMenu();
	    	 java.net.URL url = this.getClass().getResource(File.separator + "images" + File.separator + "logo.png");
	    	 Image image = Toolkit.getDefaultToolkit().getImage(url);
	    	 final TrayIcon trayIcon = new TrayIcon(image, "GV-Jclient", popup);
	    	 final SystemTray tray = SystemTray.getSystemTray();
	    	 
	         ActionListener listener = new ActionListener() {
	             public void actionPerformed(ActionEvent e) {
	            	 if("Exit".equals(e.getActionCommand()))
	            	 {
	                     tray.remove(trayIcon);
	                     System.exit(0);
	            	 }
	            	 else
	            	 setVisible(!isVisible());
	             }
	         };

	    	 MenuItem defaultItem = new MenuItem("Show/Hide");
	    	 popup.add(defaultItem);
	    	 MenuItem exitItem = new MenuItem("Exit");
	    	 exitItem.addActionListener(listener);
	    	 popup.add(exitItem);
	    	 defaultItem.addActionListener(listener);
	    	 trayIcon.addActionListener(listener);

	    	 try {
	             tray.add(trayIcon);
	         } catch (AWTException e) {
	             System.err.println(e);
	         }


	     }
	     else
	     {
	    	 
	     }
	     
	}

	private void init() {

		Account[] accounts;
		int i;
		GVJclient gvjclient;
		mainToolbar = new MainToolbar();
		this.add(mainToolbar,BorderLayout.NORTH);

		ArrayList<GVJclient> arrayList = new ArrayList<GVJclient>();
				
		//this.setLayout(new FlowLayout());
		
		accounts = readAccounts();
		for(i=0;i<accounts.length;i++)
		{
			gvjclient = new GVJclient(accounts[i]);
			arrayList.add(gvjclient);			
		}
		this.gvjclients = arrayList.toArray(new GVJclient[arrayList.size()]);	
		top = createTreeNodes();
		accountsTree = new AccountsTree(top);
		setTreeMouseListener(accountsTree);
		rightPanel = new RightPanel();
		
		//String accountName = accounts[0].getNickname();
		//String accountuserid = accounts[0].getUserId();
		//password = this.getPassword(accountuserid);
		//this.login(accountuserid,password);
		
		//phones = gvjclient.getPhoneNumbers();		
		mainPanel = new MainPanel(accountsTree, rightPanel);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.add(mainPanel);
		this.getContentPane().add(mainPanel.getSplitPane());
		//this.getRootPane().setDefaultButton(loginPanel.loginButton);
		/*JButton logoutButton = new JButton("Logout");
		logoutButton.addActionListener(GVJclientUI.get_instance());
		logoutButton.setActionCommand("LOGOUT");
		
		this.add(logoutButton);*/
		
		this.pack();
	}
	
	private Account[] readAccounts()
	{
		String fileName = System.getProperty("user.home") + File.separator +
		".gvjclient" + File.separator + "accounts.list";
		String temp;
		String[] tempArray;
		Scanner scanner = null;
		Account account;
		Account[] accounts;
		ArrayList<Account> arrayList = new ArrayList<Account>();
		try 
		{
			scanner = new Scanner(new File(fileName));
			while(scanner.hasNextLine())
			{
				temp = scanner.nextLine();
				
				if(temp.matches("([\\w-@' ]+)%([\\w-@.+]+)"))
				{
					tempArray = temp.split("%");
					System.out.println(tempArray[0]);
					account = new Account(tempArray[0],tempArray[1]);
					arrayList.add(account);
				}
			}
		} catch (IllegalStateException e) {
			
		} catch (FileNotFoundException e) {
			System.out.println("Accounts File Not Found!");
		}
		finally {
			if(scanner != null)
				scanner.close();
		}
		accounts = arrayList.toArray(new Account[arrayList.size()]);			
		return accounts;
	}
	
	private DefaultMutableTreeNode createTreeNodes()
	{
		int i;
		int j;
		DefaultMutableTreeNode top;
		DefaultMutableTreeNode clientNode;
		DefaultMutableTreeNode contactNode;
		Contact[] contacts;
		top = new DefaultMutableTreeNode(profileName);
		for(i=0;i<gvjclients.length;i++)
		{
			clientNode = new DefaultMutableTreeNode(gvjclients[i]);
			top.add(clientNode);
			contacts = gvjclients[i].getContacts();
			for(j=0;j<contacts.length;j++)
			{
				contactNode = new DefaultMutableTreeNode(contacts[j]);
				clientNode.add(contactNode);
			}
		}
		return top;
	}

	private void setTreeMouseListener(final JTree tree)
	{
        MouseListener mouseListener = new MouseAdapter() {
            public void mousePressed(MouseEvent e)
            {
            	if(e.isPopupTrigger())
            		this.showPopupMenu(e);
            }
            
            public void mouseReleased(MouseEvent e)
            {
            	if(e.isPopupTrigger())
            		this.showPopupMenu(e);
            }
            
            public void showPopupMenu(MouseEvent e)
            {
                int x;
                int y;
                int i;
                TreePath selPath;
                JPopupMenu popupMenu;
                JMenuItem menuItem;
                CallAction callAction;
                SendSMSAction smsAction;
                LoginAction loginAction;
                Contact contact;
                GVJclient client;
                Phone[] phones;
                String destinationNumber;
                DefaultMutableTreeNode treeNode;
                DefaultMutableTreeNode parentNode;
                Separator separator;
                
                x = e.getX();
                y = e.getY();
                popupMenu = new JPopupMenu();
                separator = new Separator();
                separator.setPreferredSize(new Dimension(5,5));
            	
                //selRow = tree.getRowForLocation(x, y);
            	selPath = tree.getPathForLocation(x, y);
            	
                if (selPath == null)
                    return;
                tree.setSelectionPath(selPath);
                
                treeNode = (DefaultMutableTreeNode) selPath.getLastPathComponent();
                try
                {
                	contact = (Contact)treeNode.getUserObject();
                	parentNode = (DefaultMutableTreeNode) selPath.getParentPath().getLastPathComponent();
                	client = (GVJclient)parentNode.getUserObject();
                    destinationNumber = contact.getPhone();
                    if (client.isLoggedIn())
                    {
                    	phones = client.getPhones();
                    	for(i=0;i<phones.length;i++)
                        	{
                        		callAction = new CallAction(client, phones[i],
                        								destinationNumber);
                        		menuItem = new JMenuItem(callAction);
                        		popupMenu.add(menuItem);
                        	}
                        	popupMenu.add(separator);
                        	smsAction = new SendSMSAction(client, destinationNumber);
                        	menuItem = new JMenuItem(smsAction);
                        	popupMenu.add(menuItem);
                        	
                        }
                    else
                    {
                    	menuItem = new JMenuItem("Not Logged In!");
                    	menuItem.setEnabled(false);
                		popupMenu.add(menuItem);
                		popupMenu.add(separator);
                		loginAction = new LoginAction(client);
                		menuItem = new JMenuItem(loginAction);
                		popupMenu.add(menuItem);
                    }
                } catch(ClassCastException ex)
                {
                	try
                	{
                		client = (GVJclient)treeNode.getUserObject();
                		
                		if(client.isLoggedIn())
                		{
                            phones = client.getPhones();
                            if (MouseEvent.BUTTON3 == e.getButton())
                            {
                            	for(i=0;i<phones.length;i++)
                            	{
                            		callAction = new CallAction(client, phones[i]);
                            		menuItem = new JMenuItem(callAction);
                            		popupMenu.add(menuItem);
                            	}
                            	popupMenu.add(separator);
                            	smsAction = new SendSMSAction(client);
                            	menuItem = new JMenuItem(smsAction);
                            	popupMenu.add(menuItem);
                            }
                		}
                		else
                		{
                    		loginAction = new LoginAction(client);
                    		menuItem = new JMenuItem(loginAction);
                    		popupMenu.add(menuItem);
                		}
                		
                	} catch(ClassCastException exception)
                	{
                		return;
                	}
                } finally
                {
                	popupMenu.show(tree,x,y);
                }
                        	
            }
        };
        tree.addMouseListener(mouseListener);
	}
	
	private void loginAll()
	{
		int i;
		DefaultTreeModel treeModel;
		Enumeration<TreeNode> children;
		for(i=0;i<gvjclients.length;i++)
		{
			gvjclients[i].initialLogin();
		}
		
		System.out.println("Login Successful");
		treeModel = (DefaultTreeModel)accountsTree.getModel();
		children = top.children();
		for (; children.hasMoreElements() ;) {
	    	treeModel.nodeChanged(children.nextElement());
	    	System.out.print("1");
	     }
	}
	
/*	private String getPassword(String userid)
	{
		/* Code obtained from
		 * http://blogger.ziesemer.com/2007/03/java-password-dialog.html
		 
		JLabel label = new JLabel("Please enter password for"+userid+":");
		JPasswordField passwordText = new JPasswordField();
		String password = new String();
		int result = JOptionPane.showConfirmDialog(this, new Object[]{label, passwordText},
					"Password:",JOptionPane.OK_CANCEL_OPTION);
		if ( result == JOptionPane.OK_OPTION)
		{
			password = passwordText.getText();
		}
		else
		{
			System.exit(0);
		}
		return password;
	}*/

/*	public void call(String source, String destination, String type)
	{
		try
		{
			gvjclient.call(source, destination,type);
		}catch (IOException e)
		{
			System.out.println("Error initiating the call!");
		}
	}
	public void sendSMS(String destination, String text)
	{
		/*try
		{
			gvjclient.sendSMS(destination,text);
		}catch (IOException e)
		{
			System.out.println("Error Sending the SMS!");
		}
	}*/

	public class LogoutAllAction extends AbstractAction
	{

		public LogoutAllAction()
		{
			super("Logout All");
		}
		@Override
		public void actionPerformed(ActionEvent ae)
		{
			try 
			{
				int i;
				for(i=0;i<gvjclients.length;i++)
				{
					if(gvjclients[i].isLoggedIn())
					{
						gvjclients[i].logout();
					}
				}
				System.out.println("Logged Out");
			} catch(IOException e) {
				System.out.println("Logout error");
			} finally
			{
				System.exit(0);
			}
		}
	}
}
